package com.example.skillcinema.ui.screens.main.viewmodels

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.skillcinema.db.displaymodels.FilmDisplayModel
import com.example.skillcinema.db.enums.FilmCollections
import com.example.skillcinema.db.localdb.tables.CollectionEntity
import com.example.skillcinema.db.localdb.tables.FilmEntity
import com.example.skillcinema.db.repositories.FilmForPreviewRepository
import com.example.skillcinema.db.responses.FiltersCountriesResponse
import com.example.skillcinema.db.responses.FiltersGenresResponse
import dagger.hilt.android.lifecycle.HiltViewModel
import jakarta.inject.Inject
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import retrofit2.HttpException
import java.time.LocalDate

@HiltViewModel
class MainViewModel @Inject constructor(private val repository: FilmForPreviewRepository) :
    ViewModel() {
    private val _premierStateFlow: MutableStateFlow<List<FilmDisplayModel>> =
        MutableStateFlow<List<FilmDisplayModel>>(listOf())
    val premierFlow = _premierStateFlow.asStateFlow()
    private val _isDataLoadStateFlow: MutableStateFlow<Boolean> = MutableStateFlow(false)
    val isDataLoadFlow: Flow<Boolean> = _isDataLoadStateFlow.asStateFlow()
    private val _topAllStateFlow: MutableStateFlow<List<FilmDisplayModel>> =
        MutableStateFlow<List<FilmDisplayModel>>(listOf())
    val topAllFlow = _topAllStateFlow.asStateFlow()
    private val _top250StateFlow: MutableStateFlow<List<FilmDisplayModel>> =
        MutableStateFlow<List<FilmDisplayModel>>(listOf())
    val top250Flow = _topAllStateFlow.asStateFlow()
    private val _filmFiltersStateFlow: MutableStateFlow<Pair<FiltersCountriesResponse, FiltersGenresResponse>> =
        MutableStateFlow<Pair<FiltersCountriesResponse, FiltersGenresResponse>>(
            Pair(
                FiltersCountriesResponse(1, ""), FiltersGenresResponse(1, "")
            )
        )
    val filmFilters = _filmFiltersStateFlow.asStateFlow()
    private val _filmFilteredStateFlow: MutableStateFlow<List<FilmDisplayModel>> =
        MutableStateFlow<List<FilmDisplayModel>>(listOf())
    val filmFiltered = _filmFilteredStateFlow.asStateFlow()
    private val _serialStateFlow: MutableStateFlow<List<FilmDisplayModel>> =
        MutableStateFlow<List<FilmDisplayModel>>(listOf())
    val serialFlow = _serialStateFlow.asStateFlow()


    private val today = LocalDate.now()
    private val todayPlusTwoWeek = today.plusWeeks(2)

    init {
//        viewModelScope.launch {
//            _filmFiltersStateFlow.value = repository.getRandomFilters()
//            _premierStateFlow.value =
//                repository.getPremiersForPreview(todayPlusTwoWeek.year, todayPlusTwoWeek.month)
//            _topAllStateFlow.value = repository.getTopForPreview(FilmCollections.TOP_POPULAR_ALL, 1)
//            _filmFilteredStateFlow.value = repository.getRandomFilteredFilms(
//                filmFilters.value.first.id, filmFilters.value.second.id, 1
//            )
//            _top250StateFlow.value = repository.getTopForPreview(FilmCollections.TOP_250_MOVIES, 1)
//            _serialStateFlow.value = repository.getSerialsForPreview(1)
//            _isDataLoadStateFlow.value = true
//        }
        viewModelScope.launch {
            try {
                awaitAll(
                    async {
                        val filters = repository.getRandomFilters()
                        _filmFiltersStateFlow.value = filters
                        _filmFilteredStateFlow.value =
                            repository.getRandomFilteredFilms(
                                filters.first.id,
                                filters.second.id,
                                1
                            )
                    },
                    async {
                        _premierStateFlow.value =
                            repository.getPremiersForPreview(
                                todayPlusTwoWeek.year,
                                todayPlusTwoWeek.month
                            )
                    },
                    async {
                        _topAllStateFlow.value =
                            repository.getTopForPreview(FilmCollections.TOP_POPULAR_ALL, 1)
                    },
                    async {
                        _top250StateFlow.value =
                            repository.getTopForPreview(FilmCollections.TOP_250_MOVIES, 1)
                    },
                    async {
                        _serialStateFlow.value = repository.getSerialsForPreview(1)
                    }
                )
            } catch (e: Exception) {
                throw error(e.message.toString())
            } finally {
                _isDataLoadStateFlow.value = true
            }
        }
    }
}